<template>
  <div class="profile-container">
    <el-card v-loading="loading" class="profile-card">
      <template #header>
        <div class="card-header">用户个人信息</div>
      </template>

      <el-descriptions v-if="userProfile" border column="1">
        <el-descriptions-item label="头像">
          <div>
            <img
              :src="userProfile.avatar || defaultAvatar"
              alt="用户头像"
              style="width: 100px; height: 100px; object-fit: cover"
            />
            <el-upload
              :before-upload="beforeAvatarUpload"
              :http-request="uploadAvatar"
              :show-file-list="false"
              accept="image/*"
              class="upload-avatar"
            >
              <el-button size="small" style="margin-top: 10px" type="primary">更换头像</el-button>
            </el-upload>
          </div>
        </el-descriptions-item>

        <el-descriptions-item label="用户ID">{{ userProfile.userId }}</el-descriptions-item>
        <el-descriptions-item label="用户名">{{ userProfile.username }}</el-descriptions-item>

        <el-descriptions-item label="昵称">
          <template v-if="editingNickname">
            <el-input v-model="editableNickname" clearable style="width: 300px" />
            <el-button
              :disabled="
                !editableNickname.trim() || editableNickname.trim() === userProfile.nickname
              "
              :loading="updatingName"
              size="small"
              style="margin-left: 10px"
              type="primary"
              @click="updateNickname"
            >
              保存
            </el-button>
            <el-button size="small" style="margin-left: 5px" @click="cancelEdit">取消</el-button>
          </template>
          <template v-else>
            <span>{{ userProfile.nickname }}</span>
            <el-button size="small" style="margin-left: 10px" type="text" @click="startEdit">
              编辑
            </el-button>
          </template>
        </el-descriptions-item>

        <el-descriptions-item label="邮箱">{{ userProfile.email }}</el-descriptions-item>
        <el-descriptions-item label="用户类型">{{ userProfile.role }}</el-descriptions-item>
        <el-descriptions-item label="订阅类型">
          <el-tag v-if="userProfile.subscription === 'PREMIUM'" effect="dark" type="warning">
            🌟 Premium
          </el-tag>
          <span v-else>普通用户</span>
        </el-descriptions-item>

        <el-descriptions-item v-if="userProfile.subscription === 'PREMIUM'" label="背景图片">
          <el-upload :http-request="uploadBackground" :show-file-list="false" accept="image/*">
            <el-button size="small" type="warning">上传背景图片</el-button>
          </el-upload>
        </el-descriptions-item>
        <el-descriptions-item label="账号状态">
          <el-tag :type="userProfile.active ? 'success' : 'danger'">
            {{ userProfile.active ? '已激活' : '已禁用' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="注册时间">
          {{ new Date(userProfile.createdAt).toLocaleString() }}
        </el-descriptions-item>
      </el-descriptions>

      <div style="margin-top: 20px">
        <el-button type="primary" @click="editingPassword = !editingPassword">
          {{ editingPassword ? '取消修改密码' : '修改密码' }}
        </el-button>
      </div>

      <el-form
        v-if="editingPassword"
        ref="passwordFormRef"
        :model="passwordForm"
        :rules="passwordRules"
        label-width="100px"
        style="margin-top: 20px"
      >
        <el-form-item label="当前密码" prop="password">
          <el-input v-model="passwordForm.password" show-password type="password" />
        </el-form-item>

        <el-form-item label="新密码" prop="newPassword">
          <el-input v-model="passwordForm.newPassword" show-password type="password" />
        </el-form-item>

        <el-form-item label="确认新密码" prop="confirmPassword">
          <el-input v-model="passwordForm.confirmPassword" show-password type="password" />
        </el-form-item>

        <el-form-item>
          <el-button :loading="updatingPassword" type="primary" @click="submitPasswordUpdate">
            更新密码
          </el-button>
        </el-form-item>
      </el-form>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue'
import { apiClient, handleErrorAndRedirect, uploadClient } from '@/api'
import { ElMessage } from 'element-plus'
import { eventBus } from '@/api/eventbus.ts'

interface UserDetailResponseDto {
  userId: number
  username: string
  nickname: string
  email: string
  role: 'STUDENT' | 'TEACHER' | 'ADMIN'
  active: boolean
  createdAt: string
  avatar: string
  subscription: 'NORMAL' | 'PREMIUM'
}

interface UpdateNickNameRequest {
  newNickname: string
}

interface UpdatePasswordRequest {
  password: string
  newPassword: string
}

const userProfile = ref<UserDetailResponseDto | null>(null)
const loading = ref(false)

const editableNickname = ref('')
const editingNickname = ref(false)
const updatingName = ref(false)
const editingPassword = ref(false)

const passwordForm = reactive({
  password: '',
  newPassword: '',
  confirmPassword: '',
})
const passwordFormRef = ref()
const updatingPassword = ref(false)

const passwordRules = {
  password: [{ required: true, message: '请输入当前密码', trigger: 'blur' }],
  newPassword: [{ required: true, message: '请输入新密码', trigger: 'blur' }],
  confirmPassword: [
    { required: true, message: '请确认新密码', trigger: 'blur' },
    {
      validator: (rule: any, value: string, callback: (error?: Error) => void) => {
        if (value !== passwordForm.newPassword) {
          callback(new Error('两次密码输入不一致'))
        } else {
          callback()
        }
      },
      trigger: 'blur',
    },
  ],
}

const defaultAvatar = '/default-avatar.png'

const loadUserProfile = async () => {
  loading.value = true
  try {
    const res = await apiClient.get<UserDetailResponseDto>('/user/profile')
    userProfile.value = res.data
    editableNickname.value = res.data.nickname
  } catch (error) {
    handleErrorAndRedirect(error, '加载用户信息失败')
  } finally {
    loading.value = false
  }
}

const startEdit = () => {
  editingNickname.value = true
}

const cancelEdit = () => {
  if (userProfile.value) {
    editableNickname.value = userProfile.value.nickname
  }
  editingNickname.value = false
}

const updateNickname = async () => {
  if (!editableNickname.value.trim()) {
    ElMessage.warning('昵称不能为空')
    return
  }
  if (!userProfile.value) return

  updatingName.value = true
  try {
    const payload: UpdateNickNameRequest = {
      newNickname: editableNickname.value.trim(),
    }
    await apiClient.put('/user/name/request', payload)
    ElMessage.success('昵称更新成功')
    userProfile.value.nickname = editableNickname.value.trim()
    editingNickname.value = false
  } catch (e) {
    ElMessage.error('昵称更新失败')
  } finally {
    updatingName.value = false
  }
}

const submitPasswordUpdate = () => {
  passwordFormRef.value.validate(async (valid: boolean) => {
    if (!valid) return

    updatingPassword.value = true
    try {
      const payload: UpdatePasswordRequest = {
        password: passwordForm.password,
        newPassword: passwordForm.newPassword,
      }
      await apiClient.put('/user/password/request', payload)
      ElMessage.success('密码更新成功')
      passwordForm.password = ''
      passwordForm.newPassword = ''
      passwordForm.confirmPassword = ''
      editingPassword.value = false
    } catch (e) {
      ElMessage.error('密码更新失败')
    } finally {
      updatingPassword.value = false
    }
  })
}

const uploadAvatar = async (options: any) => {
  const file = options.file
  const formData = new FormData()
  formData.append('file', file)

  try {
    const res = await uploadClient.post('/user/image', formData)
    const imageUrl = res.data.url
    await apiClient.put('/user/update-avatar', { fileUrl: imageUrl })
    ElMessage.success('头像上传成功')
    eventBus.emit('avatar-updated', imageUrl)
    await loadUserProfile()
    options.onSuccess()
  } catch (error) {
    ElMessage.error('头像上传失败')
    options.onError(error)
  }
}

const uploadBackground = async (options: any) => {
  const file = options.file
  const formData = new FormData()
  formData.append('file', file)

  try {
    const res = await uploadClient.post('/user/image', formData)
    const backgroundUrl = res.data.url
    await apiClient.put('/user/update-background', { fileUrl: backgroundUrl })
    ElMessage.success('背景图片上传成功')
    eventBus.emit('background-updated', backgroundUrl)
    await loadUserProfile()
    options.onSuccess()
  } catch (error) {
    ElMessage.error('背景图片上传失败')
    options.onError(error)
  }
}

const beforeAvatarUpload = (file: File) => {
  const isImage = file.type.startsWith('image/')
  const isLt2M = file.size / 1024 / 1024 < 20

  if (!isImage) {
    ElMessage.error('只能上传图片格式文件！')
  }
  if (!isLt2M) {
    ElMessage.error('图片大小不能超过 20MB！')
  }
  return isImage && isLt2M
}

onMounted(() => {
  loadUserProfile()
})
</script>

<style scoped>
.profile-container {
  display: flex;
  justify-content: center;
  padding: 40px 20px;
}

.profile-card {
  width: 700px;
}

.card-header {
  font-size: 20px;
  text-align: center;
  font-weight: bold;
}

.upload-avatar {
  margin-top: 10px;
}
</style>
